*> 100 Cool Things - http://cobolrocks.codeplex.com/
*> Copyright (c) 2009
*> by Emerson Lopes (emersonlopes@gmail.com)
*>
*> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
*> documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
*> the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
*> to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*>
*> The above copyright notice and this permission notice shall be included in all copies or substantial portions 
*> of the Software.
*>
*> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
*> TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
*> THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
*> CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
*> DEALINGS IN THE SOFTWARE.

CLASS-ID. PurchaseDetails AS "AdapterPattern.PurchaseDetails".

    environment division.
        configuration section.
            repository.
                interface ICreditCardAdapter      as "AdapterPattern.ICreditCardAdapter"
                class SystemString                as "System.String"
                class SystemColArrayList          as "System.Collections.ArrayList"
                class ClassProduct                as "AdapterPattern.Product"
                class ClassCustomer               as "AdapterPattern.Customer"
                class ClassVisa                   as "Legacy.VisaPaymentMethod"
                class ClassAmex                   as "Legacy.AmexPaymentMethod"
                class ClassVisaWrapper            as "AdapterPattern.VisaPaymentMethodWrapper"
                class ClassAmexWrapper            as "AdapterPattern.AmexPaymentMethodWrapper"
                class SystemObject                as "System.Object".
                
 *> Instance's data and methods
    object.
       data division.
            working-storage section.
            copy "types.book".
            
                01 anId                 type SystemInt32 value zeros.
                
            *> Properties    
                01 purchaseId           type SystemInt32                              property.
                01 totalValue           type SystemDouble                             property.
                01 aCustomer            usage object reference ClassCustomer          property.
                01 products             usage object reference SystemColArrayList     property.
                01 paymentMethod        usage object reference SystemObject           property.
                01 paymentMethodAdapter usage object reference ICreditCardAdapter     property.
                
        procedure division.
             *> ...
             
             method-id. GetDetails as "GetDetails".
             
             data division.
				working-storage section.
				01 anInteger      type SystemInt32  value zeros.
				01 amount         type SystemDouble value zeros.
				01 aProduct       usage object reference ClassProduct.
				
				linkage section.
				    01 purchaseId type SystemInt32.
			 
			 procedure division using purchaseId.
			 
			 *>  Do some DB access here and return a purchase based on its ID 
			 *>  ...
			 *>  In our example we will return a fake purchase.    
			     
			     invoke ClassCustomer "NEW" returning aCustomer 
			     
			     invoke aCustomer "GetCustomer" using 10
	
			     set purchaseId of self  to  purchaseId
			     
			     *> Lets say that even ids are going charge Amex. Odd charges Visa. 
			     
			     divide purchaseId by 2 giving anInteger remainder anInteger
			     
			     if  (anInteger = 0) then
			         set paymentMethod  to  ClassAmex::"NEW"
			     else
			         set paymentMethod  to  ClassVisa::"NEW"
			     end-if

			     *> Here would come the code to retrieve the purchase from the DB
			     *> We will simulate a purchase with 10 items
			     
			     invoke SystemColArrayList "NEW" returning products
			     
			     move   zeros           to  anId
			     
			     perform 10 times
			         invoke ClassProduct "NEW" returning aProduct
			         invoke aProduct "GetProduct" using anId 

			         invoke products "Add" using aProduct
			         
			         add    price of aProduct  to  amount
			         
			         add    1                  to  anId
                 end-perform
                 
			     set totalValue of self        to  amount.
			
			end method GetDetails.     
			
            method-id. GetDetailsAdapted as "GetDetailsAdapted".
             
             data division.
				working-storage section.
				01 anInteger      type SystemInt32  value zeros.
				01 amount         type SystemDouble value zeros.
				01 aProduct       usage object reference ClassProduct.
				
				linkage section.
				    01 purchaseId type SystemInt32.
			 
			 procedure division using purchaseId.
			 
			 *>  Do some DB access here and return a purchase based on its ID 
			 *>  ...
			 *>  In our example we will return a fake purchase.    
			     
			     invoke ClassCustomer "NEW" returning aCustomer 
			     
			     invoke aCustomer "GetCustomer" using 1

			     set purchaseId of self        to  purchaseId
			     
			     *> Lets say that even ids are going charge Amex. Odd charges Visa. 
			     
			     divide purchaseId by 2 giving anInteger remainder anInteger
			     
			     if  (anInteger = 0) then
			         invoke ClassAmexWrapper  "NEW" returning paymentMethodAdapter
			     else
			         invoke ClassVisaWrapper  "NEW" returning paymentMethodAdapter
			     end-if

			     *> Here would come the code to retrieve the purchase from the DB
			     *> We will simulate a purchase with 10 items
			     invoke SystemColArrayList "NEW" returning products
			     
			     move   zeros           to  anId
			     
			     perform 10 times
			         invoke ClassProduct "NEW" returning aProduct
			         invoke aProduct "GetProduct" using anId

			         invoke products "Add" using aProduct
			         
			         add    price of aProduct  to  amount
			         
			         add    1                  to  anId
                 end-perform
                 
			     set totalValue of self        to  amount.
			
			end method GetDetailsAdapted.     
    end object.
END CLASS PurchaseDetails.

